#ifndef DATASET_H
#define DATASET_H
#include <string>
#include <vector>
#include <map>
#include <memory>
#include "ErrorCode.h"
#include "Define.h"
#include "StoreObject.h"

namespace gitstore {

class CObjectController;
class CObjectIOBase;
struct Branch;
//struct Dataset {
//    std::string name;
//    int type;
//    std::map<std::string, std::string> keys;
//};
//class CDatasetKeysTrans;
class CDatasetController {
public:
    CDatasetController();
    virtual ~CDatasetController();

private:
    std::unique_ptr<CObjectController> _meta_op;
    std::unique_ptr<CObjectIOBase> _store_io_worker;
//    std::unique_ptr<CDatasetKeysTrans> _key_trans_op;
//public:
//    ErrorStatus beginTransaction(const std::string& ds_name);
//    ErrorStatus commitTransaction(const std::string& ds_name);
//    ErrorStatus rollbackTransaction(const std::string& ds_name);

public:
    ErrorStatus listDataset(std::vector<std::string>& vds);

    ErrorStatus createDataset(const std::string& ds_name, const std::string& ds_note, const std::string& br_name,
                              const std::string& br_note, StoreObjectType type, const std::vector<std::string>& vks,
                              const std::vector<StoreObject>& vos, int& revision_ds, int& revision_branch);

    ErrorStatus branchDataset(const std::string& ds_name, const std::string& br_refer_name, const std::string& br_new_name,
                              const std::string& br_note, int revision_refer_branch, int& revision_new_branch);

    ErrorStatus listDatasetBranches(const std::string& ds_name, std::vector<std::string>& vbr);

    ErrorStatus listDatasetKeysByBranch(const std::string& ds_name, const std::string& br_name,
                                        std::vector<std::string>& vbk, int& revision_branch);

    ErrorStatus listDatasetKeysByVersion(const std::string& ds_name, const std::string& version,
                                         std::vector<std::string>& vbk);

    ErrorStatus putKey(const std::string& ds_name, const std::string& br_name, const std::string& key,
                       const StoreObject& value, int revision_pre, int& revision_new);

    ErrorStatus getKeyByBranch(const std::string& ds_name, const std::string& br_name, const std::string& key,
                               StoreObject& value, int& revision_branch);

    ErrorStatus getKeyByVersion(const std::string& ds_name, const std::string& version,
                                const std::string& key, StoreObject& value);

    ErrorStatus getDiffKeysBranch(const std::string& ds_name, const std::string& br_name1, const std::string& br_name2,
                                  std::vector<std::string>& vks, int& revision_branch1, int& revision_branch2);

    ErrorStatus getDiffKeysVersion(const std::string& ds_name, const std::string& version1,
                                   const std::string& version2, std::vector<std::string>& vks);

    ErrorStatus getBranchInfo(const std::string& ds_name, const std::string& br_name,
                              Branch& branch, int& revision_branch);
private:
//    ErrorStatus findDiffKeys(const StoreObject& value1, const StoreObject& value2, std::vector<std::string>& vks);
};

using DatasetNode = std::map<std::string, std::string>;
//struct DatasetNode {
//    int type;
//    std::map<std::string, std::string> keys;
//};

//class CDatasetKeysTrans {
//public:
//    CDatasetKeysTrans();
//    ~CDatasetKeysTrans();
//public:
//    ErrorStatus encode(const DatasetNode& keys, std::string& str);
//    ErrorStatus decode(const std::string& str, DatasetNode& keys);
//};

}

#endif
